import type { ApiResponseSuccess } from 'axios';
import { type RowKey, DeleteInputConfirmParams } from '@ykst/components';

import { type ModalFuncProps } from 'ant-design-vue';
import { ref } from 'vue';
import type { ApiFuncData } from '@/apis/types';
import type { useFormSubmitFunc } from './useFormSubmit';
import { useAppNotification } from '../feedback/useAppNotification';
import { useAppFeedback } from '../feedback/useAppFeedback';

export interface useDeleteConfig<D, FD = D> {
  success?: (response: ApiResponseSuccess<any>) => void;
  beforeDelete?: (value: ApiFuncData<FD>) => ApiFuncData<D>;
}

export type DeleteId<FD = RowKey | RowKey[]> = FD | RowKey | RowKey[];
export interface InputDeleteConfig<D, FD = D>
  extends useDeleteConfig<D, FD>,
    Omit<DeleteInputConfirmParams, 'name'> {}

/**
 * 通用的删除请求函数，如果需要用 useDeleteConfirm
 * @param {Function} requestFunc 删除请求函数
 * @param { {beforeDelete:Function success:Function}} [config] 删除函数的请求配置
 * @param { string | boolean } [actionTitle] 表单的标题，如：设备停机记录,如果为false,不显示提示信息
 *
 * @description  泛型说明
 * - 泛型D： requestFunc的ApiFuncData.data类型，
 * - 泛型FD： 表单的data类型，默认和D一样，大部分情况FD和D不一样，
 */
export function useDelete<D, FD = D>(
  requestFunc: useFormSubmitFunc<D>,
  config: useDeleteConfig<D, FD> = {},
  actionTitle: string | boolean = '',
) {
  const { notification } = useAppNotification();

  const { success, beforeDelete } = config;
  const loading = ref(false);

  /**
   * @description 删除
   * @param { DeleteId } id 删除记录的id
   * @param { string | undefined } key 在ApiFuncData.data中的键名，可以不填
   */
  async function deleteSubmit(id: DeleteId<FD>, key?: string) {
    loading.value = true;
    let data: ApiFuncData = {
      method: 'delete',
    };
    // 只有为队形
    if (typeof key === 'string') {
      if (typeof id === 'object' && !Array.isArray(id)) {
        // 参数添加至请求体
        data.data = id;
        data.params = key;
      } else {
        data.data = {
          [key]: id,
        };
      }
    } else {
      if (Array.isArray(id)) {
        data.data = {
          ['id']: id,
        };
      } else if (typeof id === 'object') {
        // 参数添加至请求体
        data.data = id;
      } else {
        // 参数添加至路径上
        data.params = id as string;
      }
    }

    if (beforeDelete) {
      data = beforeDelete(data as ApiFuncData<FD>);
    }

    try {
      const res = await requestFunc(data as ApiFuncData<D>);
      success && (await success(res));
      actionTitle !== false &&
        notification.fastSuccess({
          message: actionTitle || '提示',
          description: `删除${actionTitle || ''}成功`,
        });
      loading.value = false;
      return res;
    } catch (e) {
      loading.value = false;
      // 已经在请求拦截中统一处理请求报错信息
      // actionTitle !== false && notification.fastError({ message: `删除${actionTitle || ''}` });
      return Promise.reject(e);
    }
  }

  return {
    deleteSubmit,
    loading,
  };
}

/**
 * @description 基于useDelete实现的确认删除，弹出确认删除框，用户点击【删除】后再删除
 * @param {Function} requestFunc 删除请求函数
 * @param { {beforeDelete:Function success:Function}} [config] 删除函数的请求配置
 * @param { string | boolean } [actionTitle] 表单的标题，如：设备停机记录,如果为false,不显示提示信息
 *
 * @description 函数和泛型说明
 * - useDelete返回的参数，在这里也会返回
 * - 泛型D： requestFunc的ApiFuncData.data类型，
 * - 泛型FD： 表单的data类型，默认和D一样，大部分情况FD和D不一样，
 */
export function useDeleteConfirm<D, FD = D>(
  requestFunc: useFormSubmitFunc<D>,
  config?: useDeleteConfig<D, FD>,
  actionTitle: string | boolean = '',
) {
  const { modal } = useAppFeedback();

  const { loading, deleteSubmit } = useDelete<D, FD>(requestFunc, config, actionTitle);
  const cLoading = ref(false);

  /**
   * @description 确认删除
   * @param { DeleteId } id 删除记录的id
   * @param { string  } [key] 在ApiFuncData.data中的键名，可以不填
   * @param { ModalFuncProps } [config] 确认弹框的配置 参数
   */
  async function deleteConfirm(
    id: DeleteId<FD>,
    key?: string,
    config?: ModalFuncProps,
  ): Promise<ApiResponseSuccess>;
  async function deleteConfirm(
    id: DeleteId<FD>,
    config?: ModalFuncProps,
  ): Promise<ApiResponseSuccess>;
  async function deleteConfirm(
    id: DeleteId<FD>,
    key?: string | ModalFuncProps,
    config?: ModalFuncProps,
  ) {
    const _key = typeof key === 'object' ? undefined : key;

    config = (typeof key === 'object' ? key : config) ?? {};
    const _config: ModalFuncProps = {
      title: '确定删除？',
      content: '删除记录后，不可恢复，是否继续删除？',
      okText: '删除',
      okType: 'danger',
      cancelText: '取消',
      ...config,
    };
    return new Promise((resolve, reject) => {
      modal.confirm({
        ..._config,
        async onOk() {
          cLoading.value = true;
          try {
            const res = await deleteSubmit(id, _key);
            resolve(res);
          } catch (error) {
            reject(error);
          }
          cLoading.value = false;
        },
        onCancel() {
          reject('cancel');
        },
      });
    });
  }
  return {
    loading,
    cLoading,
    deleteConfirm,
    deleteSubmit,
  };
}

/**
 * @deprecated 由于主题有问题，该方式暂不支持，如果需要请引入 DeleteInputConfirm 组件
 * 基于useDelete实现的输入框确认删除
 * @description 弹出输入确认删除框，用户输入要求的文字后，点击【删除】校验通过后再删除
 * @param {Function} requestFunc 删除请求函数
 * @param { {beforeDelete:Function success:Function}} [config] 删除函数的请求配置
 *
 * @description 函数和泛型说明
 *  - useDelete返回的参数，在这里也会返回
 * - 泛型D： requestFunc的ApiFuncData.data类型，
 * - 泛型FD： 表单的data类型，默认和D一样，大部分情况FD和D不一样，
 */
//
// export function useDeleteInputConfirm<D, FD = D>(
//   requestFunc: RequestFunction<any>,
//   config: InputDeleteConfig<D, FD>,
// ) {
//   const { success, beforeDelete, ...rest } = config;
//   const { loading, deleteSubmit } = useDelete<D, FD>(requestFunc, {
//     success,
//     beforeDelete,
//   });

//   /**
//    * 输入名字确认删除
//    * @param { DeleteId } id 删除记录的id
//    * @param { string } name 输入框需要输入的名字
//    * @param { string } [key] 在ApiFuncData.data中的键名，可以不填
//    * @param { Function } [callback] 成功删除后的回调
//    */
//   async function deleteConfirm(
//     id: DeleteId<FD>,
//     name: DeleteInputConfirmParams['name'],
//     key?: string,
//     callback?: (res: ApiResponse) => void,
//   ): Promise<void>;
//   async function deleteConfirm(
//     id: DeleteId<FD>,
//     name: DeleteInputConfirmParams['name'],
//     callback?: (res: ApiResponse) => void,
//   ): Promise<void>;
//   async function deleteConfirm(
//     id: DeleteId<FD>,
//     name: DeleteInputConfirmParams['name'],
//     key?: string | ((res: ApiResponse) => void),
//     callback?: (res: ApiResponse) => void,
//   ) {
//     const _key = typeof key === 'function' ? undefined : key;

//     callback = typeof key === 'function' ? key : callback;
//     await checkId(id);
//     showDeleteInputConfirm(
//       async () => {
//         const res = await deleteSubmit(id, _key);
//         callback && callback(res);
//       },
//       {
//         ...rest,
//         name,
//       },
//     );
//   }
//   return {
//     loading,
//     deleteConfirm,
//     deleteSubmit,
//   };
// }
